﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SledgeHammer;
using System.IO;

namespace wump
{
    public partial class FrmSettings : Form
    {
        Wumper wumper;

        #region Constructors

        public FrmSettings()
        {
            InitializeComponent();
        }

        public FrmSettings(Wumper activeWumper)
        {
            InitializeComponent();

            //store the wumper passed in from the parent form
            wumper = activeWumper;
        }

        #endregion

        private void FrmSettings_Load(object sender, EventArgs e)
        {
            //populate the fields on each tab
            PopulateGeneralSettings();
            PopulateLogSettings();
            PopulateEmailSettings();
        }

        #region Populate Field Functions

        private void PopulateGeneralSettings()
        {
            //fill the fields on the first tab
            txtTargetPage.Text = wumper.TargetPage;
            nudInterval.Value = (wumper.IntervalHours);

            //step through the list
            foreach (string site in wumper.Sites)
            {
                lstSites.Items.Add(site.Trim());
            }

            RefreshAutoWumpStatus();
        }

        private void PopulateLogSettings()
        {
            //fill the fields on the second tab
            chkLogResults.Checked = wumper.LogResults;
            txtLogFile.Text = wumper.LogFile;

            //load the Log file into the viewer
            LoadLog();
        }

        private void LoadLog()
        {
            //attempt to read the log file
            try
            {
                //open a new stream to the log file
                using (StreamReader sr = new StreamReader(wumper.LogFile))
                {
                    //read the log into the textbox
                    txtLog.Text = sr.ReadToEnd();
                }
            }
            catch (FileNotFoundException ex)
            {
                //if the file simply wasn't found alert the user
                txtLog.Text = "The log file could not be found.";
            }
            catch
            {
                //warn the user if it was any other error
                txtLog.Text = "An unexpected error occured attempting to access the log";
            }
        }

        private void PopulateEmailSettings()
        {
            //fill the settings on the third tab
            chkSendAlert.Checked = wumper.SendAlerts;

            //smtp settings
            txtServer.Text = wumper.SmtpServer;
            txtPort.Text = wumper.SmtpPort.ToString();
            txtUser.Text = wumper.SmtpUser;
            txtPassword.Text = wumper.SmtpPassword;

            //email settings
            txtFrom.Text = wumper.FromEmail;
            txtTo.Text = wumper.ToEmail;
            txtSubject.Text = wumper.AlertSubject;
            txtMessage.Text = wumper.AlertMessage;
        }

        #endregion

        #region OK / Cancel and support methods

        private void btnOK_Click(object sender, EventArgs e)
        {
            //if the settings are properly valid
            string validationMessages = ValidateSettings();

            if (string.IsNullOrEmpty(validationMessages))
            {
                //save the changes
                wumper.UpdateSettings(BuildSiteString(), txtTargetPage.Text,
                    (int.Parse(nudInterval.Value.ToString()) * 60), chkLogResults.Checked,
                    txtLogFile.Text, chkSendAlert.Checked, txtServer.Text, int.Parse(txtPort.Text), txtUser.Text,
                    txtPassword.Text, txtFrom.Text, txtTo.Text, txtSubject.Text, txtMessage.Text);

                //close the form
                this.Close();
            }
            else
            {
                //warn the user what is wrong
                MessageBox.Show(validationMessages, "Invalid Information", MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);
            }
        }

        private string BuildSiteString()
        {
            //step through the sites and create a string of each one seperated by a ;
            StringBuilder sb = new StringBuilder();

            foreach (string site in lstSites.Items)
            {
                sb.Append(site + ";");
            }

            //return the resulting string
            return sb.ToString();
        }

        private string ValidateSettings()
        {
            //start with a blank result string and fill it with any validation messages
            string result = string.Empty;

            //Used for try parse
            int tempInt;

            #region Tab 1 (General)

            //make sure there are sites entered
            result += (lstSites.Items.Count > 0 ? string.Empty : "At least one site must be specified to Wump" + Environment.NewLine);

            //the target page can be left blank and the interval cannot be invalid since it is
            //a numeric drop down

            #endregion

            #region Tab 2 (Log)

            //if the log is checked 
            if (chkLogResults.Checked)
            {
                //make sure there is a file name
                if (!string.IsNullOrEmpty(txtLogFile.Text))
                {
                    //make sure the path for the file exists, the file can be created later automaticaly
                    result += (Directory.Exists(Path.GetDirectoryName(txtLogFile.Text)) ? string.Empty :
                        "The directory of the log file you specified does not exist" + Environment.NewLine);
                }
                else
                {
                    result += "If you want to record to the log, you must enter a log file";
                }
            }

            #endregion

            #region Tab 3 (Alert)

            //start by checking the user has selected to send an alert
            if (chkSendAlert.Checked)
            {
                //SMTP Settings
                result += (string.IsNullOrEmpty(txtServer.Text) ||
                            string.IsNullOrEmpty(txtUser.Text) ||
                            string.IsNullOrEmpty(txtPort.Text) ||
                            string.IsNullOrEmpty(txtPassword.Text) ?
                                "All SMTP settings are required to send an alert" + Environment.NewLine :
                                string.Empty);

                result += (!string.IsNullOrEmpty(txtPort.Text) && !int.TryParse(txtPort.Text, out tempInt) ?
                    "The SMTP Port must be numeric" + Environment.NewLine :
                        string.Empty);

                //Email Settings
                result += (string.IsNullOrEmpty(txtFrom.Text) ||
                            string.IsNullOrEmpty(txtTo.Text) ||
                            string.IsNullOrEmpty(txtSubject.Text) ||
                            string.IsNullOrEmpty(txtMessage.Text) ?
                                "All email settings are required to send an alert" + Environment.NewLine :
                                string.Empty);
            }

            #endregion

            //return the validation messages or emptyString if there are none
            return result;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            //close the form and don't make any changes
            this.Close();
        }

        #endregion

        #region Tab 1 (General Settings) - GUI Events

        private void btnAdd_Click(object sender, EventArgs e)
        {
            //check the textbox is filled in
            if (!string.IsNullOrEmpty(txtSite.Text))
            {
                //check the site isn't already in the list
                if (!lstSites.Items.Contains(txtSite.Text))
                {
                    //add the site to the list
                    lstSites.Items.Add(txtSite.Text);

                    //clear out the site text box
                    txtSite.Text = string.Empty;
                }
            }
        }

        private void btnRemove_Click(object sender, EventArgs e)
        {
            //make sure there is a selection in the list
            if (lstSites.SelectedItems.Count > 0)
            {
                //remove the selected item
                lstSites.Items.Remove(lstSites.SelectedItem);
            }
        }

        private void btnAutoStartStop_Click(object sender, EventArgs e)
        {
            //disable the button until it is running or stopped
            btnAutoStartStop.Enabled = false;

            //if the text of the button is start and the service is actually stopped
            if ((btnAutoStartStop.Text.ToLower() == "start") && (svcAutoWump.Status == System.ServiceProcess.ServiceControllerStatus.Stopped))
            {
                //start the service
                svcAutoWump.Start();
            }
            else if ((btnAutoStartStop.Text.ToLower() == "stop") && (svcAutoWump.Status == System.ServiceProcess.ServiceControllerStatus.Running))
            {
                //if the service is running and the text is stop, stop it
                svcAutoWump.Stop();
            }

            //regardless of the action, refresh the service status
            RefreshAutoWumpStatus();
        }

        private void btnAutoRefresh_Click(object sender, EventArgs e)
        {
            //refresh the status of the AutoWumper
            RefreshAutoWumpStatus();
        }

        private void RefreshAutoWumpStatus()
        {
            //refresh the service controller status
            svcAutoWump.Refresh();

            //update the status label
            lblAutoWumpStatus.Text = svcAutoWump.Status.ToString();

            switch (svcAutoWump.Status)
            {
                case System.ServiceProcess.ServiceControllerStatus.StartPending:
                case System.ServiceProcess.ServiceControllerStatus.ContinuePending:
                case System.ServiceProcess.ServiceControllerStatus.PausePending:
                case System.ServiceProcess.ServiceControllerStatus.StopPending:
                    lblAutoWumpStatus.ForeColor = Color.Blue;
                    btnAutoStartStop.Enabled = false;
                    break;

                case System.ServiceProcess.ServiceControllerStatus.Running:
                    lblAutoWumpStatus.ForeColor = Color.Green;
                    btnAutoStartStop.Text = "Stop";
                    btnAutoStartStop.Enabled = true;
                    break;

                case System.ServiceProcess.ServiceControllerStatus.Paused:
                case System.ServiceProcess.ServiceControllerStatus.Stopped:
                    lblAutoWumpStatus.ForeColor = Color.Red;
                    btnAutoStartStop.Text = "Start";
                    btnAutoStartStop.Enabled = true;
                    break;

                default:
                    break;
            }
        }

        #endregion

        #region Tab 2 (Log Settings) - GUI Events

        private void chkLogResults_CheckedChanged(object sender, EventArgs e)
        {
            //enable/disbale the logFile textbox based on if this is checked or not
            txtLogFile.Enabled = chkLogResults.Checked;
        }

        private void btnClearLog_Click(object sender, EventArgs e)
        {
            //check if the file exists
            if (File.Exists(txtLogFile.Text))
            {
                try
                {
                    //open a new stream to the log file
                    using (StreamWriter sw = new StreamWriter(wumper.LogFile, false))
                    {
                        //clear the file
                        sw.Write(string.Empty);
                    }

                    //reload the log file into the viewer
                    LoadLog();
                }
                catch
                {
                    //warn the user if it was any other error
                    MessageBox.Show("An unexpected error occured attempting to clear the log", "Unable to clear the log",
                        MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
        }

        #endregion

        #region tab 3 (Alert Settings) - GUI Events

        private void chkSendAlert_CheckedChanged(object sender, EventArgs e)
        {
            //enable and disable the to group boxes based on if this is checked
            grpSMTP.Enabled = chkSendAlert.Checked;
            grpEmail.Enabled = chkSendAlert.Checked;
        }

        #endregion
        
    }
}
